package com.zzxx.shooter;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

public class ShootGame extends JPanel {
    public static BufferedImage background0 = null;
    public static BufferedImage hero0 = null;
    public static BufferedImage hero1;
    public static BufferedImage bee0 = null;
    public static BufferedImage airplane0 = null;
    public static BufferedImage bigap0 = null;
    public static BufferedImage bullet0 = null;
    public static BufferedImage start;
    public static BufferedImage pause;
    public static BufferedImage gameover;
    public static BufferedImage airplane_ember0;
    public static BufferedImage airplane_ember1;
    public static BufferedImage airplane_ember2;
    public static BufferedImage airplane_ember3;
    public static BufferedImage bee_ember0;
    public static BufferedImage bee_ember1;
    public static BufferedImage bee_ember2;
    public static BufferedImage bee_ember3;
    public static BufferedImage bigplane_ember0;
    public static BufferedImage bigplane_ember1;
    public static BufferedImage bigplane_ember2;
    public static BufferedImage bigplane_ember3;
    public static BufferedImage hero_ember0;
    public static BufferedImage hero_ember1;
    public static BufferedImage hero_ember2;
    public static BufferedImage hero_ember3;
    public static final int WIDTH = 400;
    public static final int HEIGHT = 650;



    static {
        try { // if - else
            background0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/background.png"));
            hero0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/hero0.png"));
            hero1 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/hero1.png"));
            bee0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bee.png"));
            airplane0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/airplane.png"));
            bigap0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bigplane.png"));
            bullet0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bullet.png"));
            start = ImageIO.read(ShootGame.class.getResourceAsStream("pic/start.png"));
            pause = ImageIO.read(ShootGame.class.getResourceAsStream("pic/pause.png"));
            gameover = ImageIO.read(ShootGame.class.getResourceAsStream("pic/gameover.png"));
            airplane_ember0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/airplane_ember0.png"));
            airplane_ember1 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/airplane_ember1.png"));
            airplane_ember2 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/airplane_ember2.png"));
            airplane_ember3 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/airplane_ember3.png"));
            bee_ember0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bee_ember0.png"));
            bee_ember1 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bee_ember1.png"));
            bee_ember2 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bee_ember2.png"));
            bee_ember3 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bee_ember3.png"));
            bigplane_ember0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bigplane_ember0.png"));
            bigplane_ember1 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bigplane_ember1.png"));
            bigplane_ember2 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bigplane_ember2.png"));
            bigplane_ember3 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/bigplane_ember3.png"));
            hero_ember0 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/hero_ember0.png"));
            hero_ember1 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/hero_ember1.png"));
            hero_ember2 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/hero_ember2.png"));
            hero_ember3 = ImageIO.read(ShootGame.class.getResourceAsStream("pic/hero_ember3.png"));

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    Airplane airplane;
    Airplane bigair;
    Bee bee;
    private static ArrayList<FlyingObject> flyings = new ArrayList<>();;
    private static ArrayList<Ember> bomb = new ArrayList<>();;
    private Bullet[] bullets;
    private Hero hero;
    Timer time = new Timer();

    public static final int START = 0;
    public static final int RUNNING = 1;
    public static final int PAUSE = 2;
    public static final int GAME_OVER = 3;

    private int state = 0;
    private int score = 0;







    public ShootGame(){
        start();
    }

    private void start(){
        hero = new Hero();
        bullets = new Bullet[0];
        bee = new Bee();
        airplane = new Airplane();
    }
    private int enterindex;
    public void action(){

        MouseAdapter adapter = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(state == START) {
                    state = RUNNING;
                } else if (state == GAME_OVER) {
                    state = START;
                    start();
                }
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                if (state == RUNNING) {
                    hero.setX(e.getX() - hero.width / 2);
                    hero.setY(e.getY() - hero.width / 2);
                    repaint();
                }
            }
            @Override
            public void mouseExited(MouseEvent e) {
                if(state == RUNNING){
                    state = PAUSE;
                }
            }
            @Override
            public void mouseEntered(MouseEvent e){
                if(state == PAUSE){
                    state = RUNNING;
                }
            }

        };

        addMouseListener(adapter);
        addMouseMotionListener(adapter);
        time.schedule(new TimerTask() {
            @Override
            public void run() {
                if (state == RUNNING) {
                    enterAction();
                    stepAcion();
                    shootAction();
                    bangAction();
                    outOfBoundsAction();
                    crashAction();
                    checkGameOverAction();
                    removeBomb();

                    repaint();

                }else {
                    repaint();
                }
            }
        }, 100, 10);
    }

    private void enterAction(){
        enterindex++;
        if (enterindex%10==0){
            int random = (int)(Math.random()*50);
            if(random==0){
                flyings.add(new Bee());
            }else if(random>10&&random<20) {
                flyings.add(new Airplane());
            }else if(random>25&&random<28){
                flyings.add(new BigPlane());
            }
        }
    }

    private void stepAcion(){
        for (FlyingObject object:flyings){
            object.step();
        }
        for(Bullet but :bullets){
            but.step();
        }
        hero.step();
    }

    private int shootindex;
    private void shootAction(){
        shootindex++;
        if (shootindex%30==0){
            Bullet[] bs = hero.shoot();
            bullets = Arrays.copyOf(bullets,bullets.length+bs.length);
            System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length);
        }
    }


    public void outOfBoundsAction() {
        for(int i=0;i<flyings.size();i++){
            if(flyings.get(i).outOfBound()){
                flyings.remove(i);
                i--;
            }
        }


        int num = 0;
        Bullet[] newBullet = new Bullet[bullets.length];
        for(int i = 0;i<bullets.length;i++){
            if(!bullets[i].outOfBound()){
                newBullet[num++] = bullets[i];
            }
        }
        bullets = Arrays.copyOf(newBullet,num);

    }

    public void bangAction(){
        for (int i = 0;i<bullets.length ; i++) {
            for (int j = 0;j<flyings.size();j++){
                FlyingObject fly = flyings.get(j);
                Bullet b = bullets[i];
                if(fly.shootBy(b)) {
                    bullets[i] = bullets[bullets.length - 1];
                    bullets = Arrays.copyOf(bullets, bullets.length - 1);
                    if (fly.decLife()) {
                        if(fly instanceof Award) {
                            Award award = (Award) fly;
                            int type = award.getType();
                            switch (type) {
                                case Award.DOUBLE_FIRE:
                                    hero.setDoubleFire();
                                    break;
                                case Award.ADD_LIFE:
                                    hero.addLife();
                                    break;
                            }
                        }
                        if(fly instanceof Enemy){
                            score += ((Enemy) fly).getScore();
                        }
                        Ember n = new Ember(fly);
                        bomb.add(n);
                        flyings.remove(j);
                    }
                    i--;
                    break;
                }
            }
        }
        
    }

    public void crashAction(){
        for(int i=0;i<flyings.size();i++){
            FlyingObject fly = flyings.get(i);
            if(hero.crash(fly)){
                bomb.add(new Ember(fly));
                flyings.remove(i);
                hero.subtractLife();
            };
            if (hero.getLife()<=0){
                bomb.add(new Ember(hero));
            }
        }
    }

    public void removeBomb(){
        for(int i=0; i<bomb.size(); i++) {
            Ember ember = bomb.get(i);
            ember.count();
            if(ember.getIndex()>5) {
                bomb.remove(ember);
            }
        }
    }


    public void checkGameOverAction(){
        if(hero.getLife()<=0){
            state = GAME_OVER;
        }
    }



    @Override
    // 在画板显示的时候 自动调用的
    public void paint(Graphics g) {
        super.paint(g);
        // read方法的作用: 将一张电脑磁盘中的图片, 读取到内存中, 形成一个BufferedImage对象
        // 注意: 图片和class类 在一个包中
        // g.drawImage(bigair.getImage(), airplane.getX(), airplane.getY(), this);
        Font font = new Font("Microsoft YaHei",1,20);
        // 扩展内容
        g.drawImage(background0, 0, 0, this);
        g.setFont(font);
        g.drawString("分数："+score,0,20);
        g.drawString("生命："+hero.getLife(),0,60);
        g.drawImage(hero.getImage(), hero.getX(), hero.getY(), this);

        if (state == START){
            g.drawImage(start,0,-10,this);
        }else if(state == RUNNING){
            for(FlyingObject object : flyings){
                g.drawImage(object.getImage(),object.getX(),object.getY(),this);
            }
            for (Bullet bs:bullets){
                g.drawImage(bs.getImage(),bs.getX(),bs.getY(),this);
            }
            for (Ember bomb:bomb){
                for (BufferedImage image:bomb.getImages()) {
                    int i = 0;
                    while(i%100==0) {
                        g.drawImage(image, bomb.getX(), bomb.getY(), this);
                        i++;
                    }
                }
            }

        }else if(state == PAUSE){
            g.drawImage(pause,0,0,this);
        } else if (state == GAME_OVER) {
            g.drawImage(gameover,0,0,this);
        }

        //画状态
    }

    public static void main(String[] args) {



        JFrame window = new JFrame();
//        JFrame window = new JFrame("title标题");
        window.setTitle("飞机大战");
        window.setSize(WIDTH, HEIGHT);

        window.setUndecorated(false);
        window.setLocationRelativeTo(null);
        window.setDefaultCloseOperation(3); // 0~3

        ShootGame p = new ShootGame();
        window.add(p);
        p.action();
        window.setVisible(true);
    }
}
